<script setup>
import { ref, watch } from 'vue';
import { ERROR_TYPES } from '@/utils/errorHandler';

const props = defineProps({
  error: {
    type: Object,
    default: null
  },
  message: {
    type: String,
    default: ''
  },
  type: {
    type: String,
    default: 'error' // 'error', 'warning', 'info', 'success'
  },
  duration: {
    type: Number,
    default: 5000 // 5秒后自动关闭
  },
  closable: {
    type: Boolean,
    default: true
  },
  position: {
    type: String,
    default: 'top-right' // 'top-right', 'top-left', 'bottom-right', 'bottom-left', 'top-center', 'bottom-center'
  }
});

const emit = defineEmits(['close']);

// 内部状态
const visible = ref(false);
const errorMessage = ref('');
const errorType = ref(props.type);
const timer = ref(null);

// 监听错误变化
watch(() => props.error, (newError) => {
  if (newError) {
    showError(newError);
  }
}, { deep: true });

// 监听消息变化
watch(() => props.message, (newMessage) => {
  if (newMessage) {
    errorMessage.value = newMessage;
    errorType.value = props.type;
    show();
  }
});

// 显示错误
function showError(error) {
  if (!error) return;
  
  // 设置错误消息
  if (typeof error === 'string') {
    errorMessage.value = error;
  } else if (error.message) {
    errorMessage.value = error.message;
  } else {
    errorMessage.value = '发生未知错误';
  }
  
  // 根据错误类型设置通知类型
  if (error.type) {
    switch (error.type) {
      case ERROR_TYPES.VALIDATION:
        errorType.value = 'warning';
        break;
      case ERROR_TYPES.NETWORK:
      case ERROR_TYPES.SERVER:
        errorType.value = 'error';
        break;
      case ERROR_TYPES.AUTH:
        errorType.value = 'info';
        break;
      default:
        errorType.value = 'error';
    }
  } else {
    errorType.value = props.type;
  }
  
  show();
}

// 显示通知
function show() {
  visible.value = true;
  
  // 如果设置了自动关闭
  if (props.duration > 0) {
    // 清除之前的定时器
    if (timer.value) {
      clearTimeout(timer.value);
    }
    
    // 设置新的定时器
    timer.value = setTimeout(() => {
      close();
    }, props.duration);
  }
}

// 关闭通知
function close() {
  visible.value = false;
  
  if (timer.value) {
    clearTimeout(timer.value);
    timer.value = null;
  }
  
  emit('close');
}
</script>

<template>
  <transition name="notification">
    <div 
      v-if="visible" 
      :class="['notification', `notification-${errorType}`, `notification-${position}`]"
    >
      <div class="notification-content">
        <div class="notification-icon" v-if="errorType === 'error'">
          <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
            <circle cx="12" cy="12" r="10"></circle>
            <line x1="15" y1="9" x2="9" y2="15"></line>
            <line x1="9" y1="9" x2="15" y2="15"></line>
          </svg>
        </div>
        <div class="notification-icon" v-else-if="errorType === 'warning'">
          <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
            <path d="M10.29 3.86L1.82 18a2 2 0 0 0 1.71 3h16.94a2 2 0 0 0 1.71-3L13.71 3.86a2 2 0 0 0-3.42 0z"></path>
            <line x1="12" y1="9" x2="12" y2="13"></line>
            <line x1="12" y1="17" x2="12.01" y2="17"></line>
          </svg>
        </div>
        <div class="notification-icon" v-else-if="errorType === 'info'">
          <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
            <circle cx="12" cy="12" r="10"></circle>
            <line x1="12" y1="16" x2="12" y2="12"></line>
            <line x1="12" y1="8" x2="12.01" y2="8"></line>
          </svg>
        </div>
        <div class="notification-icon" v-else-if="errorType === 'success'">
          <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
            <path d="M22 11.08V12a10 10 0 1 1-5.93-9.14"></path>
            <polyline points="22 4 12 14.01 9 11.01"></polyline>
          </svg>
        </div>
        <div class="notification-message">{{ errorMessage }}</div>
      </div>
      <button v-if="closable" class="notification-close" @click="close">
        <svg xmlns="http://www.w3.org/2000/svg" width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
          <line x1="18" y1="6" x2="6" y2="18"></line>
          <line x1="6" y1="6" x2="18" y2="18"></line>
        </svg>
      </button>
    </div>
  </transition>
</template>

<style scoped>
.notification {
  position: fixed;
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  width: 350px;
  padding: 16px;
  border-radius: 6px;
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
  background-color: white;
  z-index: 1000;
}

.notification-content {
  display: flex;
  align-items: flex-start;
}

.notification-icon {
  margin-right: 12px;
  display: flex;
  align-items: center;
  justify-content: center;
}

.notification-message {
  word-break: break-word;
  font-size: 14px;
  line-height: 1.5;
}

.notification-close {
  background: transparent;
  border: none;
  cursor: pointer;
  padding: 0;
  margin-left: 12px;
  opacity: 0.6;
  transition: opacity 0.2s;
}

.notification-close:hover {
  opacity: 1;
}

/* 通知类型样式 */
.notification-error {
  border-left: 5px solid #f44336;
}

.notification-error .notification-icon {
  color: #f44336;
}

.notification-warning {
  border-left: 5px solid #ff9800;
}

.notification-warning .notification-icon {
  color: #ff9800;
}

.notification-info {
  border-left: 5px solid #2196f3;
}

.notification-info .notification-icon {
  color: #2196f3;
}

.notification-success {
  border-left: 5px solid #4caf50;
}

.notification-success .notification-icon {
  color: #4caf50;
}

/* 位置样式 */
.notification-top-right {
  top: 20px;
  right: 20px;
}

.notification-top-left {
  top: 20px;
  left: 20px;
}

.notification-bottom-right {
  bottom: 20px;
  right: 20px;
}

.notification-bottom-left {
  bottom: 20px;
  left: 20px;
}

.notification-top-center {
  top: 20px;
  left: 50%;
  transform: translateX(-50%);
}

.notification-bottom-center {
  bottom: 20px;
  left: 50%;
  transform: translateX(-50%);
}

/* 动画 */
.notification-enter-active,
.notification-leave-active {
  transition: all 0.3s ease;
}

.notification-enter-from,
.notification-leave-to {
  opacity: 0;
  transform: translateX(30px);
}

.notification-top-center.notification-enter-from,
.notification-top-center.notification-leave-to,
.notification-bottom-center.notification-enter-from,
.notification-bottom-center.notification-leave-to {
  transform: translate(-50%, -30px);
}
</style> 